package gui;

import jahuwaldt.plot.CircleSymbol;
import jahuwaldt.plot.Plot;
import jahuwaldt.plot.Plot2D;
import jahuwaldt.plot.SimplePlotXY;

import java.awt.BorderLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Vector;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import controller.PlotController;

import database.ResultSetTableModel;

public class InternalDBBrowserPane extends JInternalFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 3482076254372525299L;

	public InternalDBBrowserPane(String title) {
		super();
		this.initialize(title);
	}

	public InternalDBBrowserPane(File file) {
		super();
		this.file = file;
		this.initialize(this.file.getPath());

	}

	private void initialize(String title) {
		initDB();

		this.setTitle(title);
		this.setResizable(true);
		this.setClosable(true);
		this.setMaximizable(true);
		this.setIconifiable(true);
		this.setSize(300, 300);
		this.setLocation(20, 20);
		this.setVisible(true);

		this.scrollPane = new JScrollPane(this.table);
		this.getContentPane().setLayout(new BorderLayout());
		this.getContentPane().add(this.selectPane, BorderLayout.NORTH);
		this.getContentPane().add(this.scrollPane);
		this.getContentPane().doLayout();
	}

	private void initDB() {
		try {
			Class.forName("org.sqlite.JDBC");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.attemptConnection();
		connection = this.connect;
		// Container pane = getContentPane();
		// this.dbPane = new JPanel();
		this.selectPane = getSelectionPanel();
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		refreshTable();
	}

	public File getFile() {
		return this.file;
	}

	protected JPanel getSelectionPanel() {
		JPanel panel = new JPanel();
		panel.add(new JLabel("Catalog"));
		panel.add(new JLabel("Schema"));
		panel.add(new JLabel("Table"));

		catalogBox = new JComboBox();
		populateCatalogBox();
		panel.add(catalogBox);
		schemaBox = new JComboBox();
		populateSchemaBox();
		panel.add(schemaBox);
		tableBox = new JComboBox();
		populateTableBox();
		panel.add(tableBox);

		catalogBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent event) {
				String newCatalog = (String) (catalogBox.getSelectedItem());
				try {
					connection.setCatalog(newCatalog);
				} catch (Exception e) {
				}
				populateSchemaBox();
				populateTableBox();
				refreshTable();
			}
		});

		schemaBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent event) {
				populateTableBox();
				refreshTable();
			}
		});

		tableBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent event) {
				refreshTable();
			}
		});
		return panel;
	}

	protected void populateCatalogBox() {
		try {
			DatabaseMetaData dmd = connection.getMetaData();
			ResultSet rset = dmd.getCatalogs();
			Vector<Object> values = new Vector<Object>();
			while (rset.next()) {
				values.addElement(rset.getString(1));
			}
			rset.close();
			catalogBox.setModel(new DefaultComboBoxModel(values));
			catalogBox.setSelectedItem(connection.getCatalog());
			catalogBox.setEnabled(values.size() > 0);
		} catch (Exception e) {
			catalogBox.setEnabled(false);
		}
	}

	protected void populateSchemaBox() {
		try {
			DatabaseMetaData dmd = connection.getMetaData();
			ResultSet rset = dmd.getSchemas();
			Vector<Object> values = new Vector<Object>();
			while (rset.next()) {
				values.addElement(rset.getString(1));
			}
			rset.close();
			schemaBox.setModel(new DefaultComboBoxModel(values));
			schemaBox.setEnabled(values.size() > 0);
		} catch (Exception e) {
			schemaBox.setEnabled(false);
		}
	}

	protected void populateTableBox() {
		try {
			String[] types = { "TABLE" };
			String catalog = connection.getCatalog();
			String schema = (String) (schemaBox.getSelectedItem());
			DatabaseMetaData dmd = connection.getMetaData();
			ResultSet rset = dmd.getTables(catalog, schema, null, types);
			Vector<Object> values = new Vector<Object>();
			while (rset.next()) {
				values.addElement(rset.getString(3));
			}
			rset.close();
			tableBox.setModel(new DefaultComboBoxModel(values));
			tableBox.setEnabled(values.size() > 0);
		} catch (Exception e) {
			tableBox.setEnabled(false);
		}
	}

	protected void refreshTable() {
		String schema = (schemaBox.isEnabled() ? schemaBox.getSelectedItem()
				.toString() : null);
		String tableName = (String) tableBox.getSelectedItem();
		if (tableName == null) {
			table.setModel(new DefaultTableModel());
			return;
		}
		String selectTable = (schema == null ? "" : schema + ".") + tableName;
		if (selectTable.indexOf(' ') > 0) {
			selectTable = "\"" + selectTable + "\"";
		}
		try {
			Statement stmt = connection.createStatement();
			ResultSet rset = stmt.executeQuery("SELECT * FROM " + selectTable);
			this.resultSetTableModel = new ResultSetTableModel(rset);
			table.setModel(this.resultSetTableModel);
			this.curPlotData = this.getPlotData();
		} catch (Exception e) {
		}
	}

	public Plot getPlotData() {
		int colCount = this.resultSetTableModel.getColumnCount();
		int rowCount = this.resultSetTableModel.getRowCount();
		double Arr[][] = new double[colCount][rowCount];
		for (int i = 0; i < colCount; i++) {
			for (int j = 0; j < rowCount; j++) {
				Arr[i][j] = (Double) this.resultSetTableModel.getValueAt(j, i);
			}
		}

		Plot2D aPlot = new SimplePlotXY(Arr[0], Arr[1], this.file.getPath(),
				this.resultSetTableModel.getColumnName(0),
				this.resultSetTableModel.getColumnName(1), null, null,
				new CircleSymbol());
		PlotController.getInstance().setCurPlotData(aPlot);
		return aPlot;

	}

	protected boolean attemptConnection() {
		try {
			connect = DriverManager.getConnection("jdbc:sqlite:"
					+ this.file.getPath());
			return true;
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, "Error connecting to "
					+ "database: " + e.getMessage());
		}
		return false;
	}

	public void setCurPlotData(Plot curPlotData) {
		this.curPlotData = curPlotData;
	}

	public Plot getCurPlotData() {
		return curPlotData;
	}

	// private JEditorPane editorPane = null;
	// private JEditorPane textArea = null;
	private JScrollPane scrollPane = null;
	private File file = null;

	protected Connection connection;

	protected JComboBox catalogBox;

	protected JComboBox schemaBox;

	protected JComboBox tableBox;

	protected JTable table = new JTable();

	protected Connection connect;

	private JPanel selectPane = null;

	private ResultSetTableModel resultSetTableModel = null;

	private Plot curPlotData = null;
}
